/**
 * @class ActionStack
 * @constructor
 */
var ActionStack = Class.create({
    initialize: function() {
        this._currentState = 0;
        this._stack        = [];
        this._MAXUNDOSIZE  = 100;
        this.saveData = "";
    },

    /**
     *
     * @method redo
     */
    redo: function() {
        var nextState = this._getNextState();
        if (!nextState) return;

        if (nextState.eventToGetToThisState) {
            var memo = nextState.eventToGetToThisState.memo;
            memo["noUndoRedo"] = true;  
            document.fire( nextState.eventToGetToThisState.eventName, memo );
            this._currentState++;
            return;
        }

        editor.getSaveLoadEngine().createGraphFromSerializedData( nextState.serializedState, true);
        this.changeDisabled();
        this._currentState++;
    },

    /**
     *
     * @method undo
     */
    undo: function() {
        var prevState = this._getPreviousState();
        if(!prevState) return;

        var currentState = this._getCurrentState();
        if (currentState.eventToUndo) {
            var memo = currentState.eventToUndo.memo;
            memo["noUndoRedo"] = true; 
            document.fire( currentState.eventToUndo.eventName, memo );
            this._currentState--;
            return;
        }

        editor.getSaveLoadEngine().createGraphFromSerializedData( prevState.serializedState, true);
        this.changeDisabled();
        this._currentState--;
    },

    /**
     *
     * @method addState
     */
    addState: function( eventToGetToThisState, eventToUndo, serializedState ) {
        if (this._currentState < this._size())
            this._stack.splice(this._currentState, this._stack.length - this._currentState);

        if (!serializedState) {
            serializedState = editor.getSaveLoadEngine().serialize();
        }
        /** edit by lizhen @2018-08-08*/ //当前数据与初始数据不相同时 禁用遗传风险评估
        this.changeDisabled();
        /*edit end*/
        
        var state = new State( serializedState, eventToGetToThisState, eventToUndo );

        var currentState = this._getCurrentState();
        if (eventToGetToThisState &&
             currentState && currentState.eventToGetToThisState &&
             currentState.eventToGetToThisState.eventName == "pedigree:node:setproperty" &&
             this._combinableEvents(currentState.eventToGetToThisState, eventToGetToThisState) ) {
            currentState.eventToGetToThisState = eventToGetToThisState;
            currentState.serializedState       = serializedState;
            return;
        }

        this._addNewest(state);
        if (this._size() > this._MAXUNDOSIZE)
            this._removeOldest();
    },
    changeDisabled(){
        var nowAllData = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, "all");
        var jsonData = JSON.parse(nowAllData);
        var nowValiData = "";
        if(jsonData && typeof(jsonData) == "object" && jsonData.length>0){
            nowValiData= this.getValidateData(jsonData);
        } 
        if(nowValiData == this.saveData){
            jQuery("#viewriskreport_button").removeAttr("disabled");
            jQuery("#viewriskreport_button").removeAttr("title");
        }else{
            jQuery("#viewriskreport_button").attr("disabled","disabled");
            jQuery("#viewriskreport_button").attr("title","请先保存再进行遗传风险评估");
        }
    },
    //获取最后一次保存的数据 /*edit by lizhen @2018-08-08*/
    setSaveData(){    
        var currentSaveJson = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, "all");
        var jsonData = JSON.parse(currentSaveJson);
        if(jsonData && typeof(jsonData) == "object" && jsonData.length>0){
            this.saveData = this.getValidateData(jsonData);
        }
    },
    //获取内容不为空的数据
    getValidateData(data){
        var ret = [];
        for(var i=0;i<data.length;i++){
            var obj = {};
            if(data[i] && typeof(data[i] == "object")){
                for(var key in data[i]){
                    if(data[i][key]){
                        obj[key] = data[i][key];
                    }
                }
            }
            ret.push(obj);
        };
        return JSON.stringify(ret);
    },
    /**
     *
     * @method _size
     * @return {Number}
     */
    _combinableEvents: function ( event1, event2 ) {
        if (!event1.memo.hasOwnProperty("nodeID") || !event2.memo.hasOwnProperty("nodeID") || event1.memo.nodeID != event2.memo.nodeID)
            return false;
        if (event1.memo.properties.hasOwnProperty("setFirstName") &&
            event2.memo.properties.hasOwnProperty("setFirstName") )
            return true;
        if (event1.memo.properties.hasOwnProperty("setLastName") &&
            event2.memo.properties.hasOwnProperty("setLastName") )
            return true;
        if (event1.memo.properties.hasOwnProperty("setLastNameAtBirth") &&
            event2.memo.properties.hasOwnProperty("setLastNameAtBirth") )
            return true;
        if (event1.memo.properties.hasOwnProperty("setComments") &&
            event2.memo.properties.hasOwnProperty("setComments") )
            return true;
        if (event1.memo.properties.hasOwnProperty("setChildlessReason") &&
            event2.memo.properties.hasOwnProperty("setChildlessReason") )
            return true;
        return false;
    },

    /**
     *
     * @method _size
     * @return {Number}
     */
    _size: function() {
        return this._stack.length;
    },

    /**
     *
     * @method _addNewest
     */
    _addNewest: function(state) {
        this._stack.push(state);
        this._currentState++;
    },

    /**
     *
     * @method _removeOldest
     */
    _removeOldest: function() {
        this._stack.splice(0, 1);
        this._currentState--;
    },

    /**
     *
     * @method _getCurrentState
     * @return {null|Object}
     */
    _getCurrentState: function() {
        return (this._size() == 0 || this._currentState == 0) ? null : this._stack[this._currentState - 1];
    },

    /**
     *
     * @method _getNextState
     * @return {null|Object}
     */
    _getNextState: function() {
        return (this._size() <= 1 || this._currentState >= this._size()) ? null : this._stack[this._currentState];
    },

    /**
     *
     * @method _getPreviousState
     * @return {null|Object}
     */
    _getPreviousState: function() {
        return (this._size() == 1 || this._currentState <= 1) ? null : this._stack[this._currentState - 2];
    },

    _debug_print_states: function() {
        console.log("------------");
        for (var i = 0; i < this._stack.length; i++) {
            console.log("[" + i + "] EventToState: " + stringifyObject(this._stack[i].eventToGetToThisState) + "\n" +
                                "    EventUndo: " + stringifyObject(this._stack[i].eventToUndo) + "\n" +
                                "    EventSerial: " + stringifyObject(this._stack[i].serializedState));
        }
        console.log("------------");
    }
});


var State = Class.create({
    initialize: function( serializedState, eventToGetToThisState, eventToUndo ) {
        this.serializedState       = serializedState;
        this.eventToGetToThisState = eventToGetToThisState;
        this.eventToUndo           = eventToUndo;
    }
});